package cn.com.dbappsecurity.frame;

import java.io.IOException;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import cn.com.dbappsecurity.frame.handler.ContraollerHandler;
import cn.com.dbappsecurity.frame.handler.LoginHandler;
import cn.com.dbappsecurity.frame.handler.TemplateHandler;
import cn.com.dbappsecurity.frame.scanner.Actions;
import cn.com.dbappsecurity.frame.scanner.ControllerScanner;
import cn.com.dbappsecurity.frame.scanner.Controllers;
import cn.com.dbappsecurity.utils.ObjectUtil;

public class DispatcherFilter implements Filter {
	
	private static final Logger LOG = Logger.getLogger(DispatcherFilter.class);
	
	//缓存controller列表
    private Map<String,Controllers> controllersMap;
    //缓存template列表
    private Map<String,Controllers> templatesMap;
	
    //处理器
    private LoginHandler loginHandler;
    private ContraollerHandler contraollerHandler;
    private TemplateHandler templateHandler;
    
	public void destroy() {
	}
	
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//统一处理编码
		request.setCharacterEncoding(Constant.ENCODING);
		response.setContentType("text/html; charset="+Constant.ENCODING);
		response.setCharacterEncoding(Constant.ENCODING);
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse resp = (HttpServletResponse)response;
		
		String uri = req.getRequestURI().substring(req.getContextPath().length());
		if(uri.endsWith("/")){
			uri += Constant.DEFAULT_URI + Constant.TEMPLATE_SUFFIX;
		}else if(!uri.substring(uri.lastIndexOf("/")).contains(".")){
			uri += "/" + Constant.DEFAULT_URI + Constant.TEMPLATE_SUFFIX;
		}
		//访问控制器
		boolean ajaxReq = uri.endsWith(Constant.CONTROLLER_SUFFIX);
		boolean pageReq = uri.endsWith(Constant.TEMPLATE_SUFFIX);
		if(ajaxReq || pageReq){
			//登录验证
			if(!loginHandler.execute(req,resp)){
				return;
			}
			//取得控制器配置
			String className;
			String methodName;
			uri = uri.substring(0,uri.lastIndexOf("."));
			if(ajaxReq){
				int lastIndexPt = uri.lastIndexOf(".");
				className = uri.substring(uri.lastIndexOf("/")+1,lastIndexPt);
				methodName = uri.substring(lastIndexPt+1);
			}else{
				int lastIndexSep = uri.lastIndexOf("/");
				if(lastIndexSep == 0){
					className = "";
				}else{
					className = uri.substring(1,lastIndexSep);
				}
				methodName = uri.substring(lastIndexSep+1);
			}
			Controllers controllers = ajaxReq ? controllersMap.get(className) : templatesMap.get(className);
			Actions actions = null;
			if(controllers != null){
				actions = controllers.getMethod(methodName);
			}
			//调用控制器
			if(ajaxReq){
				contraollerHandler.execute(controllers,actions,req,resp);
			}else{
				templateHandler.execute(className,methodName,controllers,actions,req,resp);
			}
		}else{
			chain.doFilter(req,resp);
		}
	}

	/**
	 * 初始化
	 */
	public void init(FilterConfig fConfig){
		String controllerPackage = ObjectUtil.getString(fConfig.getInitParameter("controllerPackage"),null);
		String templatePackage = ObjectUtil.getString(fConfig.getInitParameter("templatePackage"),null);
		if(controllerPackage == null){
			LOG.error("未配置控制器路径");
			System.exit(0);
		}
		try {
			//扫描并注册controller
			controllersMap = ControllerScanner.scanControllersFromPackges(controllerPackage.split(","));
			//扫描并注册template
			templatesMap = ControllerScanner.scanControllersFromPackges(templatePackage.split(","));
			//随系统启动的任务
			startTask(ObjectUtil.getString(fConfig.getInitParameter("tasks"),null));
			//处理器初始化
			loginHandler = new LoginHandler();
			contraollerHandler = new ContraollerHandler();
			templateHandler = new TemplateHandler(fConfig.getServletContext());
		} catch (Exception e) {
			LOG.error("初始化异常",e);
			System.exit(0);
		}
	}
	
	/*
	 * 启动任务
	 * @param tasks
	 * @throws Exception
	 */
	private void startTask(String tasks)throws Exception{
		if(!StringUtils.isBlank(tasks)){
			String[] paths = tasks.split(",");
			for(String path : paths){
				String[] entry = path.split(":");
				LOG.debug("启动任务：" + entry[0]);
				Class<?> clazz = Class.forName(entry[0]);
				clazz.getMethod(entry[1]).invoke(clazz.newInstance());
			}
		}
	}
	
}
